#ifndef PIZZA_HPP_
# define PIZZA_HPP_

# include <iostream>
# include <list>
# include "Utils/ISerializable.hpp"
# include "PizzaRecipe.hpp"

namespace pizzeria {

/* \class Pizza
 * Describe a pizza
 */
class Pizza: public utils::ISerializable {
public:
  /*! Available type for pizzas */
  enum TypePizza {
    Regina = 1,
    Margarita = 2,
    Americaine = 4,
    Fantasia = 8
  };

  /*! Size disponibles for les pizzas (...) */
  enum TaillePizza {
    S = 1,
    M = 2,
    L = 4,
    XL = 8,
    XXL = 16
  };

  typedef TypePizza PizzaType; /*!< Alias for enum TypePizza */
  typedef TaillePizza PizzaSize; /*!< Alias for enum TaillePizza */

  /*! Default constructor
   * Create a pizza of type PizzaType::Regina and of size PizzaSize::S
   */
  Pizza();
  /*! Constructor
   * \param pizzaType: the type of the pizza
   * \param pizzaSize: the size of the pizza
   */
  Pizza(PizzaType pizzaType, PizzaSize pizzaSize);
  /*! Copy constructor
   * \param toCopy : the \a Pizza object to copy
   */
  Pizza(const Pizza &from);
  /*! Destructor */
  ~Pizza();

  /*! Asignement operator
   * \param toCopy : the \a Pizza object to copy
   * \return A reference on \a this \a Pizza object
   */
  Pizza &operator=(const Pizza &toCopy);

  /*! Get the pizza size
   * \return The pizza size
   */
  PizzaSize GetSize() const;
  /*! Set the pizza size */
  void SetSize(PizzaSize size);
  /*! Get the pizza type
   * \return The pizza type
   */
  PizzaType GetType() const;
  /*! Set the pizza type */
  void SetType(PizzaType type);

  /* Get valid type tokens
   * \return A std::list of the valids tokens as std::string
   */
  static std::list<std::string> GetListOfValidTypeString();
  /* Get valid size tokens
   * \return A std::list of the valids tokens as std::string
   */
  static std::list<std::string> GetListOfValidSizeString();

  /*! Serialize the object
   * \return a std::string representing the serialized data
   */
  std::string Serialize() const;
  /*! Deserialize the object
   * \param data : data to deserialize
   */
  void Deserialize(const std::string &data);
  /*! Get size of serialized data
   * \return size of serialized data
   */
  size_t GetSerializedSize() const;

  const PizzaRecipe &GetPizzaRecipe() const;

private:
  PizzaType mType; /*!< Type of the pizza */
  PizzaSize mSize; /*!< Size of the pizza */

  /*! The recipe for this pizza (ingredients, cooking time, ...) */
  PizzaRecipe mPizzaRecipe;
};

} /* !namespace pizzeria */
#endif /* !PIZZA_HPP_ */
